﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
//using System.Drawing.
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Microsoft.Win32;
using Color = System.Drawing.Color;

using Image = System.Drawing.Image;
using PixelFormat = System.Drawing.Imaging.PixelFormat;

namespace PictureConverter
{
    public partial class MainWindow : Window
    {
        private string loadedImagePath = "";
        private byte[]? originalPngData;

        public MainWindow()
        {
            InitializeComponent();
            ConvertButton.IsEnabled = false;
        }

        private void ClearButton_Click(object sender, RoutedEventArgs e)
        {
            PreviewImage.Visibility = Visibility.Collapsed;
            DropText.Visibility = Visibility.Visible;
            loadedImagePath = "";
            ConvertButton.IsEnabled = false;
        }

        private void SelectFile_Click(object sender, RoutedEventArgs e)
        {
            var openFileDialog = new OpenFileDialog
            {
                Filter = "PNG files (*.png)|*.png",
                Title = "Select a PNG image"
            };

            if (openFileDialog.ShowDialog() == true)
            {
                LoadImage(openFileDialog.FileName);
            }
        }

        private void DropArea_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effects = DragDropEffects.Copy;
                var border = (sender as Grid).Parent as Border;
                border.BorderBrush = new SolidColorBrush(Colors.DodgerBlue);
            }
            else
            {
                e.Effects = DragDropEffects.None;
            }
        }

        private void DropArea_DragLeave(object sender, DragEventArgs e)
        {
            var border = (sender as Grid).Parent as Border;
            border.BorderBrush = new SolidColorBrush(Color.FromArgb(68, 68, 68).ToMediaColor());
        }

        private void DropArea_Drop(object sender, DragEventArgs e)
        {
            var border = (sender as Grid).Parent as Border;
            border.BorderBrush = new SolidColorBrush(Color.FromArgb(68, 68, 68).ToMediaColor());

            if (!e.Data.GetDataPresent(DataFormats.FileDrop))
                return;

            var files = (string[])e.Data.GetData(DataFormats.FileDrop);
            if (files.Length > 0 && Path.GetExtension(files[0]).ToLower() == ".png")
            {
                LoadImage(files[0]);
            }
        }

        private void LoadImage(string path)
        {
            try
            {
                loadedImagePath = path;
                originalPngData = File.ReadAllBytes(path);

                var bitmapImage = new BitmapImage();
                bitmapImage.BeginInit();
                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                bitmapImage.UriSource = new Uri(path);
                bitmapImage.EndInit();

                PreviewImage.Source = bitmapImage;
                PreviewImage.Visibility = Visibility.Visible;
                DropText.Visibility = Visibility.Collapsed;
                ConvertButton.IsEnabled = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Error loading image: {ex.Message}", "Error",
                    MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void ConvertButton_Click(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrEmpty(loadedImagePath))
                return;

            var saveFileDialog = new SaveFileDialog
            {
                Filter = "ICO files (*.ico)|*.ico",
                Title = "Save ICO file"
            };

            if (saveFileDialog.ShowDialog() == true)
            {
                try
                {
                    // 获取选中的尺寸
                    var sizes = new List<int>();
                    if (Size16.IsChecked == true) sizes.Add(16);
                    if (Size32.IsChecked == true) sizes.Add(32);
                    if (Size48.IsChecked == true) sizes.Add(48);
                    if (Size64.IsChecked == true) sizes.Add(64);
                    if (Size128.IsChecked == true) sizes.Add(128);
                    if (Size256.IsChecked == true) sizes.Add(256);

                    if (sizes.Count == 0)
                    {
                        MessageBox.Show("Please select at least one icon size", "Warning",
                            MessageBoxButton.OK, MessageBoxImage.Warning);
                        return;
                    }

                    using (var originalImage = Image.FromFile(loadedImagePath))
                    {
                        var iconData = GenerateIcon(originalImage, sizes, TransparencyCheckBox.IsChecked == true);
                        File.WriteAllBytes(saveFileDialog.FileName, iconData);
                    }

                    MessageBox.Show("ICO file created successfully!", "Success",
                        MessageBoxButton.OK, MessageBoxImage.Information);
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"Error creating ICO file: {ex.Message}", "Error",
                        MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }

        public static byte[] GenerateIcon(Image sourceImage, List<int> sizes, bool maintainTransparency)
        {
            // 创建源图像的缩略图
            var images = new List<Bitmap>();
            foreach (var size in sizes)
            {
                var img = ResizeImage(sourceImage, size, size, maintainTransparency);
                images.Add(img);
            }

            // 创建ICO文件
            using (var stream = new MemoryStream())
            {
                // ICO文件头
                stream.Write(new byte[] { 0x00, 0x00, 0x01, 0x00 }, 0, 4); // 图标类型 (1 = ico)
                stream.WriteByte((byte)images.Count);
                stream.WriteByte(0x00);

                // 计算偏移量
                int offset = 6 + (16 * images.Count);

                // 写目录项
                for (int i = 0; i < images.Count; i++)
                {
                    var img = images[i];
                    byte width = (img.Width == 256) ? (byte)0 : (byte)img.Width;
                    byte height = (img.Height == 256) ? (byte)0 : (byte)img.Height;

                    stream.WriteByte(width); // 宽度
                    stream.WriteByte(height); // 高度
                    stream.WriteByte(0); // 调色板数量（无调色板）
                    stream.WriteByte(0); // 保留字节

                    if (maintainTransparency)
                    {
                        stream.Write(new byte[] { 0x00, 0x00 }, 0, 2); // 颜色平面（通常为0）
                        stream.Write(new byte[] { 32, 0 }, 0, 2); // 每像素位数 (32位)
                    }
                    else
                    {
                        stream.Write(new byte[] { 0x00, 0x00 }, 0, 2); // 颜色平面
                        stream.Write(new byte[] { 24, 0 }, 0, 2); // 每像素位数 (24位)
                    }

                    using (var pngStream = new MemoryStream())
                    {
                        if (maintainTransparency)
                        {
                            img.Save(pngStream, ImageFormat.Png);
                        }
                        else
                        {
                            // 对于不透明图片，转换为32bpp格式但Alpha设置为不透明
                            var opaqueImg = new Bitmap(img.Width, img.Height, PixelFormat.Format32bppRgb);
                            using (var g = Graphics.FromImage(opaqueImg))
                            {
                                g.CompositingQuality = CompositingQuality.HighQuality;
                                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                                g.SmoothingMode = SmoothingMode.HighQuality;
                                g.DrawImage(img, 0, 0, img.Width, img.Height);
                            }
                            opaqueImg.Save(pngStream, ImageFormat.Png);
                        }

                        byte[] pngData = pngStream.ToArray();
                        var size = pngData.Length;

                        stream.Write(BitConverter.GetBytes(size), 0, 4); // 图像数据大小
                        stream.Write(BitConverter.GetBytes(offset), 0, 4); // 图像数据偏移量
                        offset += size;
                    }
                }

                // 写图像数据
                for (int i = 0; i < images.Count; i++)
                {
                    var img = images[i];
                    using (var pngStream = new MemoryStream())
                    {
                        if (maintainTransparency)
                        {
                            img.Save(pngStream, ImageFormat.Png);
                        }
                        else
                        {
                            var opaqueImg = new Bitmap(img.Width, img.Height, PixelFormat.Format32bppRgb);
                            using (var g = Graphics.FromImage(opaqueImg))
                            {
                                g.CompositingQuality = CompositingQuality.HighQuality;
                                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                                g.SmoothingMode = SmoothingMode.HighQuality;
                                g.DrawImage(img, 0, 0, img.Width, img.Height);
                            }
                            opaqueImg.Save(pngStream, ImageFormat.Png);
                        }

                        byte[] pngData = pngStream.ToArray();
                        stream.Write(pngData, 0, pngData.Length);
                    }

                    img.Dispose(); // 释放图像资源
                }

                return stream.ToArray();
            }
        }

        private static Bitmap ResizeImage(Image sourceImage, int width, int height, bool maintainTransparency)
        {
            var destRect = new Rectangle(0, 0, width, height);
            var destImage = new Bitmap(width, height,
                maintainTransparency ? PixelFormat.Format32bppArgb : PixelFormat.Format24bppRgb);

            destImage.SetResolution(sourceImage.HorizontalResolution, sourceImage.VerticalResolution);

            using (var graphics = Graphics.FromImage(destImage))
            {
                graphics.CompositingMode = CompositingMode.SourceCopy;
                graphics.CompositingQuality = CompositingQuality.HighQuality;
                graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                graphics.SmoothingMode = SmoothingMode.HighQuality;
                graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

                // 确保绘图操作使用高质量设置
                using (var wrapMode = new ImageAttributes())
                {
                    wrapMode.SetWrapMode(WrapMode.TileFlipXY);
                    graphics.DrawImage(sourceImage, destRect, 0, 0, sourceImage.Width, sourceImage.Height,
                        GraphicsUnit.Pixel, wrapMode);
                }
            }

            return destImage;
        }
    }

    public static class ColorExtensions
    {
        public static System.Windows.Media.Color ToMediaColor(this System.Drawing.Color color)
        {
            return System.Windows.Media.Color.FromArgb(color.A, color.R, color.G, color.B);
        }
    }
}